<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>防抖与节流</title>
  </head>
  <body>
    <!-- 
      节流: n 秒内只运行一次，若在 n 秒内重复触发，只有一次生效
      防抖: n 秒后在执行该事件，若在 n 秒内被重复触发，则重新计时
    -->
    <button onclick="log1(1)">防抖</button>
    <button onclick="log2(2)">节流</button>
    <script>
      function show(event) {
        console.log("防抖", event);
      }

      /*
        防抖函数：利用延迟器实现
      */
      function _debounce(fn, delay = 500) {
        let timer = null;
        return function () {
          // 通过闭包清理上一个延迟器
          if (timer) clearTimeout(timer);
          timer = setTimeout(() => {
            // 改变this指向，将修饰后的函数参数赋给原函数(arguments)
            fn.apply(this, arguments);
            timer = null; //
          }, delay);
        };
      }
      // 调用防抖函数
      let log1 = _debounce(show, 1000);

      /*
        节流函数:利用时间戳实现
      */
      function _throttled(fn, delay = 500) {
        let timer = null;
        let nowTime = Date.now();
        return function () {
          // 还在时间段之内，不二次触发回调
          if (Date.now() - nowTime < delay) return;
          // delay时间已过，重置
          nowTime = Date.now();
          fn.apply(this, arguments);
        };
      }

      function show2(event) {
        console.log("节流", event);
      }

      // 调用节流函数
      let log2 = _throttled(show2, 2000);
    </script>
  </body>
</html>
